package com.kordar.admin.modular.sys.controller;

import com.alibaba.fastjson.JSON;
import com.kordar.admin.kernel.util.HelperUtil;
import com.kordar.admin.kernel.util.SpringUtil;
import com.kordar.admin.kernel.wrapper.BatchDeleteWrapperEntity;
import com.kordar.datalist.ResultEntity;
import com.kordar.rbac.*;
import lombok.Data;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.ServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Controller
@RequestMapping("sys")
public class RbacController {

    final
    AuthManager authManager;

    public RbacController(AuthManager authManager) {
        this.authManager = authManager;
    }

    @GetMapping("permission/index")
    public String permission(Model model) {
        model.addAttribute("data", JSON.toJSONString(authManager.getPermissions()));
        return "pages/modular/system/rbac/permission/index";
    }

    @RequestMapping(value = "permission/add", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ResultEntity<Object> permissionAdd(Item item) {
        Permission permission = authManager.createPermission(item.getName());
        permission.setDescription(item.getDescription());
        try {
            authManager.add(permission);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultEntity<>(1, "添加失败【查看是否新增结点已存在】");
        }
        return new ResultEntity<>();
    }

    @RequestMapping(value = "permission/delete", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ResultEntity<Object> permissionDelete(String name) {
        try {
            Permission permission = authManager.getPermission(name);
            authManager.remove(permission);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultEntity<>(1, e.getMessage());
        }
        return new ResultEntity<>();
    }

    @GetMapping("role/index")
    public String role(Model model) {
        model.addAttribute("data", JSON.toJSONString(authManager.getRoles()));
        return "pages/modular/system/rbac/role/index";
    }

    @RequestMapping(value = "role/add", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ResultEntity<Object> roleAdd(Item item) {
        Role role = authManager.createRole(item.getName());
        role.setDescription(item.getDescription());
        try {
            authManager.add(role);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultEntity<>(1, e.getMessage());
        }
        return new ResultEntity<>();
    }

    @RequestMapping(value = "role/delete", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ResultEntity<Object> roleDelete(String name) {
        try {
            Role role = authManager.getRole(name);
            authManager.remove(role);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultEntity<>(1, "添加失败【查看是否新增角色已存在】");
        }
        return new ResultEntity<>();
    }

    @RequestMapping(value = "role/assign", method = {RequestMethod.GET})
    public String roleAssign(Model model, String id) {
        model.addAttribute("roleId", id);
        List<String> children = authManager.getChildren(id).stream().map(Item::getName).collect(Collectors.toList());
        model.addAttribute("children", children);
        model.addAttribute("pTree", JSON.toJSONString(HelperUtil.layuiPermissionTree(authManager.getPermissions())));
        model.addAttribute("rTree", JSON.toJSONString(HelperUtil.layuiRoleTree(authManager.getRoles(), id)));
        return "pages/modular/system/rbac/role/assign";
    }

    @Data
    private static class AssignBody {
        private String id;
        private Set<String> ids;
        private Integer type = ItemEnum.TYPE_PERMISSION.getCode();
    }

    @RequestMapping(value = "role/assign/add", method = {RequestMethod.POST})
    @ResponseBody
    public ResultEntity<Object> roleAssignAdd(@RequestBody AssignBody assignBody) {
        Role role = authManager.getRole(assignBody.getId());
        if (role == null) {
            return ResultEntity.error("未知角色");
        }

        for (String name : assignBody.getIds()) {
            Item item = assignBody.getType().equals(ItemEnum.TYPE_PERMISSION.getCode()) ? authManager.getPermission(name) : authManager.getRole(name);
            if (item != null && authManager.canAddChild(role, item)) {
                try {
                    authManager.addChild(role, item);
                } catch (Exception e) {}
            }
        }
        return new ResultEntity<>();
    }

    @RequestMapping(value = "role/assign/del", method = {RequestMethod.POST})
    @ResponseBody
    public ResultEntity<Object> roleAssignDel(@RequestBody AssignBody assignBody) {
        Role role = authManager.getRole(assignBody.getId());
        if (role == null) {
            return ResultEntity.error("未知角色");
        }

        for (String name : assignBody.getIds()) {
            Item item = assignBody.getType().equals(ItemEnum.TYPE_PERMISSION.getCode()) ? authManager.getPermission(name) : authManager.getRole(name);
            if (item != null) {
                authManager.removeChild(role, item);
            }
        }
        return new ResultEntity<>();
    }

    @RequestMapping(value = "permission/scan")
    @ResponseBody
    public ResultEntity<Object> scanPermission(String filter) {
        HelperUtil.scanPermission(filter, authManager);
        return ResultEntity.success();
    }

    @RequestMapping("permission/batch-delete")
    @ResponseBody
    public ResultEntity<Object> del(ServletRequest request, @RequestBody BatchDeleteWrapperEntity<String> entity) {
        Set<String> ids = entity.getIds();
        ids.forEach(id -> {
            Permission permission = authManager.createPermission(id);
            authManager.remove(permission);
        });
        return new ResultEntity<>();
    }

}
